#include "PlotFrameHandler.h"


enum Ids
{
	// id for sockets
	PLOT_TIMER_ID = 1001
};

enum SocketId
{
	// id for sockets
	SERVER_ID = 100,
	SOCKET_ID,
	TIMER_ID
};

BEGIN_EVENT_TABLE( PlotFrameHandler, wxFrame )
EVT_TIMER(PLOT_TIMER_ID,PlotFrameHandler::RefreshUI)
EVT_BUTTON(wxID_FREEZE,PlotFrameHandler::OnFreeze)
EVT_BUTTON(wxID_PLAY,PlotFrameHandler::OnPlay)
EVT_BUTTON(wxID_ZOOMIN,PlotFrameHandler::OnZoomIn)
EVT_BUTTON(wxID_ZOOMOUT,PlotFrameHandler::OnZoomOut)
EVT_SCROLL(PlotFrameHandler::Scroll)  
EVT_SIZE(PlotFrameHandler::OnResize)
EVT_CHOICE(wxID_CHOICE_FILTER,PlotFrameHandler::OnChangeFilter)
EVT_CHOICE(wxID_CHOICE_LEAD,PlotFrameHandler::OnChangeLead) 
EVT_KEY_DOWN(PlotFrameHandler::OnKeyDown)
//EVT_BUTTON(wxID_Hide,PlotFrameHandler::OnHide)
EVT_BUTTON(wxID_Show,PlotFrameHandler::OnShow)
EVT_BUTTON(wxID_TRIG0,PlotFrameHandler::OnTrigger)
EVT_BUTTON(wxID_TRIG1,PlotFrameHandler::OnTrigger)
EVT_BUTTON(wxID_TRIG2,PlotFrameHandler::OnTrigger)
EVT_BUTTON(wxID_TRIG3,PlotFrameHandler::OnTrigger)
EVT_BUTTON(wxID_TRIG4,PlotFrameHandler::OnTrigger)
EVT_BUTTON(wxID_TRIG5,PlotFrameHandler::OnTrigger)
END_EVENT_TABLE()

PlotFrameHandler::PlotFrameHandler(wxWindow *parent, int id, int PlotsNumber,wxString *pLabels, int SampleFreq ,int PlotSeconds,float *Max,float *Min, Instrument* pInstrument) : PlotFrame(parent,id)
{
	yLabel = L"";
	TheoreticalFrequency = SampleFreq;
	PlotSecondsPerPage	= PlotSeconds;
	pNavigator = pInstrument;
	PlotsPerPage = 8;
	m_SigPlot = NULL;
	CurveCount = PlotsNumber;
	Pages = ceil(((float)PlotsNumber)/PlotsPerPage);
	PlotLength	=	PlotSeconds * SampleFreq;
	Frequency	=	SampleFreq;

	for(int i=0;i<PlotsNumber;i++)
	{
		pChLin[i] = new SignalClass();	
		pChLin[i]->SetSignal(Min[i],Max[i],1,BLUE,pLabels[i],yLabel,500,PlotSecondsPerPage,TheoreticalFrequency);
	}
	//RedrawSema.Post();
	
	SetPages();
	
	memset(RegsCurves,0,sizeof(RegsCurves));
	m_PlayButton->Enable();
	m_FreezeButton->Disable();
	m_Lead->Select(0);
	
	for(int p=0;p<Filter.FilterNumber;p++)
	{
		m_Processing->Insert(Filter.Filters[p].Name,p+1);	
	}

	m_Processing->Select(0);
	m_PlayButton->Disable();
	m_FreezeButton->Disable();
	

	CurrentSpatialFilter = LINEAR;
	
	isRunning = false;
	memset(&Info,0,sizeof(Info));
	Info.BeginTime = GetTickCount();
	Info.ElapsedTime = 0;
	Info.Errors = 0;
	Info.EstimatedFrequency = 0;
	Info.ReceivedSamples = 0;
	Layout();
	StartDrawing();
}

PlotFrameHandler::~PlotFrameHandler(void)
{

	SignalClass *pTemp;
	Timer.Stop();
	for(int i= 0; i<CurveCount;i++)
	{
		pTemp = pChLin[i];
		pChLin[i] = NULL;
		if(pTemp!=NULL)	delete pTemp;
	}
	//Cancellare tutto
}


void PlotFrameHandler::RefreshUI(wxTimerEvent& Event)
{
	//RedrawSema.Wait();
	if(m_SigPlot != NULL)	
	{
		m_SigPlot->DrawAll();
	}
	if (isRunning)
	{
		unsigned int Elap = (GetTickCount()-Info.BeginTime)/1000;
		mySampleFreq->SetLabel(wxString::Format(_T("%.1f Hz"),Info.EstimatedFrequency));
		myElapTime->SetLabel(wxString::Format(_T("%d:%d"),Elap/60,Elap%60));
		mySample->SetLabel(wxString::Format(_T("%d"),Info.ReceivedSamples));
		myError->SetLabel(wxString::Format(_T("%d"),Info.Errors));
	}
	//RedrawSema.Post();
}


void PlotFrameHandler::OnFreeze(wxCommandEvent& Event)
{
	Event.Skip();
	Timer.Stop();
	m_PlayButton->Enable();
	m_FreezeButton->Disable();
	ZoomIn->Disable();
	ZoomOut->Disable();
}
void PlotFrameHandler::StartDrawing(void)
{
//	if(pDataSplit == NULL) return;
		
	Timer.SetOwner( this,PLOT_TIMER_ID);
	Timer.Start(REDRAW_INTERVAL);
	
	m_PlayButton->Disable();
	m_FreezeButton->Enable();
	ZoomIn->Enable();
	ZoomOut->Enable();
//	panel->m_ReshapeButton->Enable();
	
}
void PlotFrameHandler::OnPlay(wxCommandEvent& Event)
{
	Event.Skip();
	StartDrawing();
	//RegisterPlots(LINEAR);
}
void PlotFrameHandler::OnChangeFilter(wxCommandEvent& Event)
{
	int Sel = m_Processing->GetCurrentSelection();
	Filter.SelectFilter(Sel-1);
}
void PlotFrameHandler::OnChangeLead(wxCommandEvent& Event)
{
	CurrentSpatialFilter = m_Lead->GetCurrentSelection()+1;
	
	switch(CurrentSpatialFilter)
	{
	case LINEAR:
	case CAR:
		break;
	}
}

#include <math.h>
void PlotFrameHandler::OnIdle(wxIdleEvent &event)
{
	event.Skip();
	/*if(RedrawSema.TryWait()!=wxSEMA_BUSY && IsShown())
	{
		int Time = GetTickCount();
		if(m_SigPlot != NULL)	
		{
			m_SigPlot->DrawAll();
		}
		Time = GetTickCount()-Time;
		//pCurrPanel->m_SigPlot->Redraw(wxPLOTCTRL_REDRAW_PLOT);
		unsigned int Elap = (GetTickCount()-Info.BeginTime)/1000;
		m_FreqLog->SetLabel(wxString::Format(_T("Estimated Frequency: %.1f Hz"),Info.EstimatedFrequency));
		m_ElapsedLog->SetLabel(wxString::Format(_T("Elapsed time: %d:%d"),Elap/60,Elap%60));
		m_ReceivedLog->SetLabel(wxString::Format(_T("Received Samples %d"),Info.ReceivedSamples));
		m_ErrorsLog->SetLabel(wxString::Format(_T("Time to plot %d"),Time));
	}*/
}

void PlotFrameHandler::PutSample(SampleStruct Sample)
{
	if (this->IsShown())
	{
		int i;
		float mean;
		//RedrawSema.Wait();
	
		Filter.FilterSample(&Sample.Data);

		mean = 0;
		if(CurrentSpatialFilter == CAR)
		{
			for(i=0;i<CurveCount;i++)
			{
				mean += Sample.Data.Signal[i];
			}
			mean = mean / CurveCount;
		}
		for(i=0;i<CurveCount;i++)
		{
			pChLin[i]->AddData(Sample.Data.Signal[i]-mean);
		}
		if(Sample.Events.HIMTrigg != 0) 
		{
			irr::video::SColor color;
			switch (Sample.Events.HIMTrigg)
			{
			case 1:	
				color = RED;
				break;
			case 2: 
				color = BLUE;
				break;
			case 3:
				color = GREEN;
				break;
			case 4:
				color = BROWN;
				break;
			case 5:
				color = YELLOW;
				break;
			case 6:
				color = PINK;
				break;
			default:
				color = WHITE;
				break;
			}
			m_SigPlot->SetTrigger(1,color,wxString::Format(_("%d"),Sample.Events.HIMTrigg));
		}
		if(Sample.Events.AEnimaTrigg != 0)
		{
			m_SigPlot->SetTrigger(2,ORANGE,wxString::Format(_("%d"),Sample.Events.AEnimaTrigg));
		}
		if(Sample.Events.HWTrigger != 0)
		{
			m_SigPlot->SetTrigger(3,BLACK,wxString::Format(_("%d"),Sample.Events.HWTrigger));
		}
	}
	//RedrawSema.Post();
	/*Sample.Signal[0]= ((float)(0+ rand() %10))/10*2-1;
	Sample.Signal[1]= 1;*/
//	panel[0]->m_SigPlot->AddData(&Sample.Signal[0]);



	/*switch(CurrentSpatialFilter)
	{
	case LINEAR:
		for(i=0;i<CurveCount;i++) pChLin[i]->PutSample(Sample.Signal[i]);
	break;
	case CAR:
		mean = 0;
		for(i=0;i<CurveCount;i++) mean += Sample.Signal[i];
		mean = mean/CurveCount;
		for(i=0;i<CurveCount;i++) pChLin[i]->PutSample(Sample.Signal[i]-mean);
	break;
	case BIPOLAR:
		for(i=0;i<CurveCount;i+=2) pChLin[i]->PutSample(Sample.Signal[i]-Sample.Signal[i+1]);
		break;
	}*/
}

void PlotFrameHandler::OnChangePage( wxCommandEvent& event )
{
	RegisterPlots();
}
void PlotFrameHandler::RegisterPlots()
{
	int SigOffset,SigNum;
	m_SigPlot->ResetCurves();
	int CurrPage = m_Page->GetCurrentSelection();
	SigOffset = CurrPage * PlotsPerPage;
	SigNum = CurveCount - SigOffset;	
	if(SigNum > PlotsPerPage) SigNum = PlotsPerPage;
	for(int i = SigOffset;i<(SigOffset+SigNum);i++)
	{
		m_SigPlot->AddCurve(pChLin[i]);
	}
	
}

void PlotFrameHandler::OnResize(wxSizeEvent& event)
{
	//Timer.Stop();
	if(IsShown())
	{
		Layout();
		wxSize newSize = m_HelpPanel->GetSize();
		if(m_SigPlot != NULL)
		{
			PlotSecondsPerPage = m_SigPlot->secLength;
			TheoreticalFrequency = m_SigPlot->SampleFreq;
			PlotSizer->Detach(m_SigPlot);
			m_SigPlot->Engine->device->getGUIEnvironment()->clear();
			delete m_SigPlot;
		}	
		m_SigPlot = new Plot(m_HelpPanel,newSize.x,newSize.y,TheoreticalFrequency,PlotSecondsPerPage*TheoreticalFrequency,L"sec",yLabel,5,true,true/*,CurveCount*/);
		RegisterPlots();
		PlotSizer->Add(m_SigPlot,1,wxEXPAND);
		PlotSizer->Layout();
		Layout();
//		secValue->SetLabel(wxString::Format(_("%d"),m_SigPlot->secLength));
//		m_slider->SetValue(m_SigPlot->secLength);
		m_SigPlot->DrawAll();
	}
}
void PlotFrameHandler::OnChannelNumber( wxSpinEvent& event )
{
	PlotsPerPage = m_spinCtrl1->GetValue();
	if (PlotsPerPage>CurveCount)
	{
		PlotsPerPage = CurveCount;
		m_spinCtrl1->SetValue(PlotsPerPage);
	}
	SetPages(); //Update m_Page command
	RegisterPlots(); //

}

void PlotFrameHandler::SetPages(void)
{
	Pages = ceil(((float)CurveCount)/PlotsPerPage);
	m_Page->Clear();
	for(int u = 0;u<Pages;u++)	
	{
		m_Page->Insert(wxString::Format(_("%d"),u+1),u);
		m_Page->SetSelection( 0 );
	}
}

void PlotFrameHandler::OnZoomIn(wxCommandEvent& event)
{
	if (m_SigPlot->numSignals==0)
		return;
	int sec = pChLin[0]->secLength;
	if (sec>1)
	{
		ZoomOut->Enable();
		if (sec<=10)
			sec--;
		else if (sec<=30)
			sec-=2;
		else 
			sec-=5;

		for(int i=0;i<m_SigPlot->numSignals;i++)
		{
			/*delete [] pChLin[i]->data2Plot;
			delete [] pChLin[i]->dataRecorded;*/
			free (pChLin[i]->data2Plot);
			free (pChLin[i]->dataRecorded);
			pChLin[i]->SetSignal(pChLin[i]->MinDyn, pChLin[i]->MaxDyn, pChLin[i]->Gain, pChLin[i]->Color, pChLin[i]->Label, 
				pChLin[i]->UnitLabel, pChLin[i]->lGraph, sec, m_SigPlot->SampleFreq); 
			pChLin[i]->gCursor=0;
			pChLin[i]->gEndCursor = pChLin[i]->gCursor+20;
			pChLin[i]->cursor=0;
			pChLin[i]->ResizeTo(pChLin[i]->lGraph);
		}
		m_SigPlot->secLength = sec;
		if (sec==1)
			ZoomIn->Disable();
		else
			ZoomIn->Enable();
	}
	else
		ZoomIn->Disable();
}

void PlotFrameHandler::OnZoomOut(wxCommandEvent& event)
{
	if (m_SigPlot->numSignals==0)
		return;
	int sec = pChLin[0]->secLength;
	if (sec<60)
	{
		ZoomIn->Enable();
		if (sec<10)
			sec++;
		else if (sec<30)
			sec+=2;
		else 
			sec+=5;

		for(int i=0;i<m_SigPlot->numSignals;i++)
		{
			//delete [] pChLin[i]->data2Plot;
			//delete [] pChLin[i]->dataRecorded;
			free (pChLin[i]->data2Plot);
			free (pChLin[i]->dataRecorded);

			pChLin[i]->SetSignal(pChLin[i]->MinDyn, pChLin[i]->MaxDyn, pChLin[i]->Gain, pChLin[i]->Color, pChLin[i]->Label, 
				pChLin[i]->UnitLabel, pChLin[i]->lGraph, sec, m_SigPlot->SampleFreq); 
			pChLin[i]->gCursor=0;
			pChLin[i]->gEndCursor = pChLin[i]->gCursor+20;
			pChLin[i]->cursor=0;
			pChLin[i]->ResizeTo(pChLin[i]->lGraph);
		}
		m_SigPlot->secLength = sec;
		if (sec==60)
			ZoomOut->Disable();
		else
			ZoomOut->Enable();
	}
	else
		ZoomOut->Disable();
}

void PlotFrameHandler::OnKeyDown(wxKeyEvent &event)
{
	return;
}


void PlotFrameHandler::CleanPlot(void)
{
	if(IsShown())
	{
		int sec = m_SigPlot->secLength;
		for(int i=0;i<m_SigPlot->numSignals;i++)
		{
			free (pChLin[i]->data2Plot);
			free (pChLin[i]->dataRecorded);
			pChLin[i]->SetSignal(pChLin[i]->MinDyn, pChLin[i]->MaxDyn, pChLin[i]->Gain, pChLin[i]->Color, pChLin[i]->Label, 
				pChLin[i]->UnitLabel, pChLin[i]->lGraph, sec, m_SigPlot->SampleFreq); 
			pChLin[i]->gCursor=0;
			pChLin[i]->gEndCursor = pChLin[i]->gCursor+20;
			pChLin[i]->cursor=0;
			pChLin[i]->ResizeTo(pChLin[i]->lGraph);
		}
	}
}

void PlotFrameHandler::OnHide(wxCommandEvent &Event)
{
	PlotControlsOpened->Hide();
	PlotControlsClosed->Show();
	plot_control_panel->Show(false);
	ControlPanel->Layout();
	ControlPanel->Fit();
	this->Fit();

}

void PlotFrameHandler::OnShow(wxCommandEvent &Event)
{
	plot_control_panel->Show(true);
	PlotControlsOpened->Show();
	PlotControlsClosed->Hide();
	ControlPanel->Layout();
	ControlPanel->Fit();
}
void PlotFrameHandler::OnTrigger(wxCommandEvent& event)
{
	int Flag;
	switch(event.GetId())
	{
	case wxID_TRIG0:
		Flag = 1;
		break;
	case wxID_TRIG1:
		Flag = 2;
		break;
	case wxID_TRIG2:
		Flag = 3;
		break;
	case wxID_TRIG3:
		Flag = 4;
		break;
	case wxID_TRIG4:
		Flag = 5;
		break;
	case wxID_TRIG5:
		Flag = 6;
		break;
	}
	if(pNavigator != NULL)
	{
		pNavigator->SetHIMTrigger(Flag);
		pNavigator->pOutLog->AppendText(wxString::Format(_("Trigger %d\n"),Flag));
		pNavigator->pOutLog2->Clear();
		pNavigator->pOutLog2->AppendText(wxString::Format(_("Trigger %d\n"),Flag));
	}
}